#include "skill.h"
#include "skillsynergy.h"
#include "description.h"


namespace
{
QString fs_CHECK_DESC_NAME = "Check Description";
QString fs_SPECIAL_DESC_NAME = "Special Description";
QString fs_RESTRICTIONS_DESC_NAME = "Restrictions Description";
QString fs_USE_UNTRAINED_DESC_NAME = "Use Untrained Description";
QString fs_TRY_AGAIN_DESC_NAME = "Try Again Description";
}

Skill::Skill(QObject *parent) :
    ModelItem(parent),
    m_keyAbility(0),
    m_tryAgain(false),
    m_useUntrained(false),
    m_armorCheckPenalty(false),
    m_action(0)
{
    qRegisterMetaType<SkillSynergies*>();
    qRegisterMetaType<Description*>();
}

Skill::Skill(const Skill& other) :
    ModelItem(other),
    m_keyAbility(other.keyAbility()),
    m_tryAgain(other.tryAgain()),
    m_useUntrained(other.useUntrained()),
    m_armorCheckPenalty(other.armorCheckPenalty()),
    m_action(other.action())
{
}

int Skill::keyAbility() const
{
    return m_keyAbility;
}

bool Skill::tryAgain() const
{
    return m_tryAgain;
}

bool Skill::useUntrained() const
{
    return m_useUntrained;
}

bool Skill::armorCheckPenalty() const
{
    return m_armorCheckPenalty;
}

int Skill::action() const
{
    return m_action;
}

void Skill::setKeyAbility(int arg)
{
    if (m_keyAbility != arg) {
        m_keyAbility = arg;
        emit keyAbilityChanged(arg);
    }
}

void Skill::setTryAgain(bool arg)
{
    if (m_tryAgain != arg) {
        m_tryAgain = arg;
        emit tryAgainChanged(arg);
    }
}

void Skill::setUseUntrained(bool arg)
{
    if (m_useUntrained != arg) {
        m_useUntrained = arg;
        emit useUntrainedChanged(arg);
    }
}

void Skill::addSkillSynergy(Skill *skill)
{
    SkillSynergies* synergies = findChild<SkillSynergies*>(QString(), Qt::FindDirectChildrenOnly);
    if (!synergies)
    {
        synergies = new SkillSynergies(this);
    }

    foreach (const SkillSynergy* synergy, synergies->findChildren<SkillSynergy*>(QString(), Qt::FindDirectChildrenOnly))
    {
        if (synergy->referenceItem() == skill)
        {
            return;
        }
    }

    SkillSynergy* synergy = synergies->createItem();
    synergy->setReferenceItem(skill);
}

QString Skill::check() const
{
    Description* desc = findDescription(fs_CHECK_DESC_NAME);
    if (!desc)
    {
        return QString();
    }

    return desc->text();
}

QString Skill::special() const
{
    Description* desc = findDescription(fs_SPECIAL_DESC_NAME);
    if (!desc)
    {
        return QString();
    }

    return desc->text();
}

QString Skill::restrictions() const
{
    Description* desc = findDescription(fs_RESTRICTIONS_DESC_NAME);
    if (!desc)
    {
        return QString();
    }

    return desc->text();
}

QString Skill::tryAgainDescription() const
{
    Description* desc = findDescription(fs_TRY_AGAIN_DESC_NAME);
    if (!desc)
    {
        return QString();
    }

    return desc->text();
}

QString Skill::useUntrainedDescription() const
{
    Description* desc = findDescription(fs_USE_UNTRAINED_DESC_NAME);
    if (!desc)
    {
        return QString();
    }

    return desc->text();
}

void Skill::setAction(int arg)
{
    if (m_action != arg) {
        m_action = arg;
        emit actionChanged(arg);
    }
}

void Skill::setCheck(QString arg)
{
    Description* desc = findDescription(fs_CHECK_DESC_NAME);
    if (!desc)
    {
        desc = new Description(this);
        desc->setName(fs_CHECK_DESC_NAME);
        connect(desc, &Description::textChanged, this, &Skill::checkChanged);
    }

    desc->setText(arg);
}

void Skill::setSpecial(QString arg)
{
    Description* desc = findDescription(fs_SPECIAL_DESC_NAME);
    if (!desc)
    {
        desc = new Description(this);
        desc->setName(fs_SPECIAL_DESC_NAME);
        connect(desc, &Description::textChanged, this, &Skill::specialChanged);
    }

    desc->setText(arg);
}

void Skill::setRestrictions(QString arg)
{
    Description* desc = findDescription(fs_RESTRICTIONS_DESC_NAME);
    if (!desc)
    {
        desc = new Description(this);
        desc->setName(fs_RESTRICTIONS_DESC_NAME);
        connect(desc, &Description::textChanged, this, &Skill::restrictionsChanged);
    }

    desc->setText(arg);
}

void Skill::setTryAgainDescription(QString arg)
{
    Description* desc = findDescription(fs_TRY_AGAIN_DESC_NAME);
    if (!desc)
    {
        desc = new Description(this);
        desc->setName(fs_TRY_AGAIN_DESC_NAME);
        connect(desc, &Description::textChanged, this, &Skill::tryAgainDescriptionChanged);
    }

    desc->setText(arg);
}

void Skill::setUseUntrainedDescription(QString arg)
{
    Description* desc = findDescription(fs_USE_UNTRAINED_DESC_NAME);
    if (!desc)
    {
        desc = new Description(this);
        desc->setName(fs_USE_UNTRAINED_DESC_NAME);
        connect(desc, &Description::textChanged, this, &Skill::useUntrainedDescriptionChanged);
    }

    desc->setText(arg);
}

Description* Skill::findDescription(QString name) const
{
    foreach (Description* desc, findChildren<Description*>(QString(), Qt::FindDirectChildrenOnly))
    {
        if (desc->name() != name)
        {
            continue;
        }

        return desc;
    }

    return 0;
}

void Skill::setArmorCheckPenalty(bool arg)
{
    if (m_armorCheckPenalty != arg) {
        m_armorCheckPenalty = arg;
        emit armorCheckPenaltyChanged(arg);
    }
}


